<?php
	require_once dirname(dirname(dirname(dirname(__FILE__)))) . '/config/cConfig.php';
	$codeConfig = new \ampleharvest\code\cConfig();
	
	require_once(dirname(dirname(dirname(__FILE__)))) . '/cAmpleHarvestLog.php';

	require_once $codeConfig->C_STR_SOLR_LIB_PATH . "/Document.php";
	class cDoc
	{
		const C_STR_FIELD_CLASSIFICATION = "classification";
		const C_STR_FIELD_CLIENT = "client";
		const C_STR_FIELD_CONTENT = "content";
		const C_STR_FIELD_HARVEST_DATE = "harvest_date";
		const C_STR_FIELD_ID = "id";
		const C_STR_FIELD_INDEX_DATE = "index_date";
		const C_STR_FIELD_LANGUAGE = "language";
		const C_STR_FIELD_LIKED = "liked";
		const C_STR_FIELD_ORIG_ID = "origId";
		const C_STR_FIELD_PROPERTY_OPTIONS = "propertyOptions";
		const C_STR_FIELD_PUBLISH_DATE = "publish_date";
		const C_STR_FIELD_TITLE = "title";
		const C_STR_FIELD_SOURCE = "source";
		const C_STR_FIELD_SCORE = "score";
		const C_STR_FIELD_SUMMARY = "summary";
		const C_STR_FIELD_TAGS = "tags";
		const C_STR_FIELD_VIEWED = "viewers";

		const C_STR_DATATYPE_DATE = "date";
		const C_STR_DATATYPE_STRING = "string";
		const C_STR_DATATYPE_VALUE = "value";

		const C_STR_RE_DATE_TIME = "/^\d{4}\/\d{1,2}\/\d{1,2}T\d{1,2}:\d{1,2}:\d{1,2}$/";
		const C_STR_RE_DATE = "/^\d{4}\/\d{1,2}\/\d{1,2}T$/";

		const C_STR_FORMAT_DATE = "Y-m-d\TH:i:s\Z";

		private $m_arr_Values = array();
		protected $m_obj_Log = null;

		function __construct(DateTime $obj_IndexDate = null)
		{
			$this->m_obj_Log = new cAmpleHarvestLog();

			if (!isset($obj_IndexDate))
			{
				$obj_IndexDate = new DateTime();
			}
			$obj_IndexDate->setTimezone(new DateTimeZone('GMT'));
			$this->set_Field(self::C_STR_FIELD_INDEX_DATE, $obj_IndexDate->format(self::C_STR_FORMAT_DATE));

		}

		function load_FromJson($obj_Json)
		{
			$this->m_obj_Log->do_Log(cAmpleHarvestLog::C_STR_ACTION_DATA_INDEX_INFO,
				"Loading Data from Json.",
				cAmpleHarvestLog::C_INT_LEVEL_DEBUG);

			$this->m_obj_Log->do_Log(cAmpleHarvestLog::C_STR_ACTION_DATA_INDEX_INFO,
				"Json Parsed Successfuly.",
				cAmpleHarvestLog::C_INT_LEVEL_DEBUG);

			if (isset($obj_Json->classification))
			{
				$this->set_Field(self::C_STR_FIELD_CLASSIFICATION, $obj_Json->classification);
			}
			else
			{
				$this->m_obj_Log->do_Log(cAmpleHarvestLog::C_STR_ACTION_DATA_INDEX_INFO,
					"Json Object does not contain the Expected Classification object.",
					cAmpleHarvestLog::C_INT_LEVEL_DEBUG);
			}

			if (isset($obj_Json->origId))
			{
				$this->set_Field(self::C_STR_FIELD_ORIG_ID, $obj_Json->origId);
			}
			else
			{
				$this->m_obj_Log->do_Log(cAmpleHarvestLog::C_STR_ACTION_DATA_INDEX_INFO,
					"Json Object does not contain the Expected origId object.",
					cAmpleHarvestLog::C_INT_LEVEL_DEBUG);
			}

			if (isset($obj_Json->language))
			{
				$this->set_Field(self::C_STR_FIELD_LANGUAGE, $obj_Json->language);
			}

			if (isset($obj_Json->source))
			{
				$this->set_Field(self::C_STR_FIELD_SOURCE, $obj_Json->source);
			}
			else
			{
				$this->m_obj_Log->do_Log(cAmpleHarvestLog::C_STR_ACTION_DATA_INDEX_INFO,
					"Json Object does not contain the Expected source object.",
					cAmpleHarvestLog::C_INT_LEVEL_DEBUG);
			}

			if (isset($obj_Json->publishDate))
			{
				try
				{
					$this->set_DateField(self::C_STR_FIELD_PUBLISH_DATE, $obj_Json->publishDate);
				}
				catch (Exception $e)
				{
					print($obj_Json->id . " Date Error");
				}
			}
			else
			{
				$this->m_obj_Log->do_Log(cAmpleHarvestLog::C_STR_ACTION_DATA_INDEX_INFO,
					"Json Object does not contain the Expected publishDate object.",
					cAmpleHarvestLog::C_INT_LEVEL_DEBUG);
			}

			if (isset($obj_Json->harvestDate))
			{
				$this->set_DateField(self::C_STR_FIELD_HARVEST_DATE, $obj_Json->harvestDate);
			}
			else
			{
				$this->m_obj_Log->do_Log(cAmpleHarvestLog::C_STR_ACTION_DATA_INDEX_INFO,
					"Json Object does not contain the Expected harvestDate object.",
					cAmpleHarvestLog::C_INT_LEVEL_DEBUG);
			}

			if (isset($obj_Json->id))
			{
				$this->set_Field(self::C_STR_FIELD_ID, $obj_Json->id);
			}
			else
			{
				$this->m_obj_Log->do_Log(cAmpleHarvestLog::C_STR_ACTION_DATA_INDEX_INFO,
					"Json Object does not contain the Expected id object.",
					cAmpleHarvestLog::C_INT_LEVEL_DEBUG);
			}

			if (isset($obj_Json->title))
			{
				$this->set_Field(self::C_STR_FIELD_TITLE, $obj_Json->title);
			}
			else
			{
				$this->set_Field(self::C_STR_FIELD_TITLE, "No Title");
				$this->m_obj_Log->do_Log(cAmpleHarvestLog::C_STR_ACTION_DATA_INDEX_INFO,
					"Json Object does not contain the Expected title object.",
					cAmpleHarvestLog::C_INT_LEVEL_DEBUG);
			}

			if (isset($obj_Json->summary))
			{
				$this->set_Field(self::C_STR_FIELD_SUMMARY, $obj_Json->summary);
			}
			else
			{
				$str_Summary = "";
				if (isset($obj_Json->content))
				{
					$str_Summary = substr(strip_tags($obj_Json->content), 0, 200);
				}

				if (!$str_Summary)
				{
					$str_Summary = "No Summary Available.";
				}
				@$str_Summary = iconv(mb_detect_encoding($str_Summary), "UTF-8//IGNORE", $str_Summary);

				$this->set_Field(self::C_STR_FIELD_SUMMARY, $str_Summary);
			}

			if (isset($obj_Json->content))
			{
				$this->set_Field(self::C_STR_FIELD_CONTENT, strip_tags($obj_Json->content));
			}
			else
			{
				$this->m_obj_Log->do_Log(cAmpleHarvestLog::C_STR_ACTION_DATA_INDEX_INFO,
					"Json Object does not contain the Expected content object.",
					cAmpleHarvestLog::C_INT_LEVEL_DEBUG);
			}

			if (isset($obj_Json->enhancement))
			{
				$this->process_Enhancements($obj_Json->enhancement);
			}

			if (isset($obj_Json->m_obj_Views))
			{
				foreach ($obj_Json->m_obj_Views as $str_View)
				{
					//print("View - ".$str_View."\n");
					$this->set_Field(self::C_STR_FIELD_VIEWED, $str_View, false);
				}
			}

			return true;
		}

		private function process_Enhancements($obj_Enhancements)
		{
			if (isset($obj_Enhancements->CCE))
			{
				$this->process_CCE($obj_Enhancements->CCE);
			}

			if (isset($obj_Enhancements->hierarchy))
			{
				if (isset($obj_Enhancements->hierarchy->data))
				{
					$this->process_Hierarchy($obj_Enhancements->hierarchy->data);
				}
			}

			if (isset($obj_Enhancements->metadata))
			{
				$this->process_Metadata($obj_Enhancements->metadata);
			}
		}

		private function process_CCE($obj_CCE)
		{
			if (isset($obj_CCE->CCEEntities))
			{
				$this->process_CCEEntities($obj_CCE->CCEEntities);
			}

			if (isset($obj_CCE->CCEValues))
			{
				$this->process_CCEValues($obj_CCE->CCEValues);
			}
		}

		private function get_DataType($mix_Data)
		{
			if (is_numeric($mix_Data))
			{
				return self::C_STR_DATATYPE_VALUE;
			}
			$obj_Date = null;
			try
			{
				$obj_Date = new DateTime($mix_Data);
			}
			catch (Exception $e)
			{
			}

			if ($obj_Date)
			{
				return self::C_STR_DATATYPE_DATE;
			}
			return self::C_STR_DATATYPE_STRING;
		}

		private function process_NameValue($obj_Data, $str_NameID = "name", $str_ValueID = "value")
		{
			if ((!isset($obj_Data->$str_NameID)) || (!isset($obj_Data->$str_ValueID)))
			{
				print("Name - " . $obj_Data->$str_NameID . "\n");
				print("Value - " . $obj_Data->$str_ValueID . "\n");
				print("Missing Value or Name\n");
				return;
			}
			$str_DataType = $this->get_DataType($obj_Data->$str_ValueID);

			$obj_Data->$str_NameID = strtolower(str_ireplace(" ", "_", $obj_Data->$str_NameID));

			switch ($str_DataType)
			{
				case self::C_STR_DATATYPE_DATE:
					$obj_Date = new DateTime($obj_Data->$str_ValueID);
					$obj_Date->setTimezone(new DateTimeZone('GMT'));
					$this->set_Field($str_DataType . "." . $obj_Data->$str_NameID, $obj_Date->format(cSolr::C_STR_FORMAT_DATE), false);
					$this->set_Field(self::C_STR_DATATYPE_STRING . "." . $obj_Data->$str_NameID, $obj_Date->format(cSolr::C_STR_FORMAT_DATE), false);
					$this->set_Field(self::C_STR_FIELD_PROPERTY_OPTIONS, $str_DataType . "." . $obj_Data->$str_NameID, false);
					break;
				case self::C_STR_DATATYPE_VALUE:
					$this->set_Field($str_DataType . "." . $obj_Data->$str_NameID, $obj_Data->$str_ValueID, false);
					$this->set_Field(self::C_STR_DATATYPE_STRING . "." . $obj_Data->$str_NameID, $obj_Data->$str_ValueID, false);
					$this->set_Field(self::C_STR_FIELD_PROPERTY_OPTIONS, $str_DataType . "." . $obj_Data->$str_NameID, false);
					break;
				default:
					$this->set_Field($str_DataType . "." . $obj_Data->$str_NameID, $obj_Data->$str_ValueID, false);
			}

			$this->set_Field(self::C_STR_FIELD_PROPERTY_OPTIONS, self::C_STR_DATATYPE_STRING . "." . $obj_Data->$str_NameID, false);
		}

		private function process_Hierarchy($arr_Data)
		{
			foreach ($arr_Data as $key => $obj_Data)
			{
				$this->process_NameValue($obj_Data);
			}
		}

		private function process_Metadata($arr_Metadata)
		{
			foreach ($arr_Metadata as $obj_Metadata)
			{
				$this->process_NameValue($obj_Metadata);
			}
		}

		private function process_CCEEntities($arr_Entities)
		{
			$this->process_CCEData($arr_Entities);
			//print_r($arr_Entities);
		}

		private function process_CCEValues($arr_Values)
		{
			$this->process_CCEData($arr_Values);
			//print_r($arr_Entities);
		}

		private function process_CCEData($arr_Data)
		{
			//print_r($arr_Data);
			foreach ($arr_Data as $obj_Data)
			{
				if (isset($obj_Data->type) && isset($obj_Data->text))
				{
					$arr_List = array();

					foreach ($obj_Data->CCEOccurrences as $obj_Object)
					{
						if (isset($obj_Object->mentionType))
						{
							$arr_List[$obj_Object->mentionType] = $obj_Data->text;
						}
						else
						{
							$arr_List["name"] = $obj_Data->text;
						}
					}

					foreach ($arr_List as $key => $text)
					{
						//print($obj_Data->type . "." . $key." - $text\n");
						$this->set_Field($obj_Data->type . "." . $key, $text, false);
						$this->set_Field(self::C_STR_FIELD_PROPERTY_OPTIONS, $obj_Data->type . "." . $key, false);
					}
				}
			}
		}

		public function set_DateField($str_Field, $str_Value, $bool_Overwrite = true)
		{
			$obj_Date = new DateTime($str_Value);
			$obj_Date->setTimezone(new DateTimeZone('GMT'));
			if ($obj_Date)
			{
				$this->set_Field($str_Field, $obj_Date->format(self::C_STR_FORMAT_DATE), $bool_Overwrite);
			}
		}

		public function set_Field($str_Field, $str_Value, $bool_Overwrite = true)
		{
			//print($str_Field ." - ". $str_Value."\n");

			$arr_Fields = array();

			if (preg_match('/^entity/', $str_Field))
			{
				$arr_Options = preg_split("/\./", $str_Field);
				$str_Field = ""; //$arr_Options[0];

				foreach ($arr_Options as $str_Section)
				{
					if ($str_Field)
					{
						$str_Field .= ".";
					}
					$str_Field .= $str_Section;
					$arr_Fields[] = $str_Field;
				}
			}
			else
			{
				$arr_Fields[] = $str_Field;
			}

			foreach ($arr_Fields as $str_Field)
			{
				//print($str_Field . " - " . $str_Value . "\n");
				if ($bool_Overwrite)
				{
					$this->m_arr_Values[$str_Field] = $str_Value;
				}
				else
				{
					if (isset($this->m_arr_Values[$str_Field]))
					{
						$arr_Data = array();
						if (is_array($this->m_arr_Values[$str_Field]))
						{
							$arr_Data = $this->m_arr_Values[$str_Field];
						}
						else
						{
							$arr_Data[] = $this->m_arr_Values[$str_Field];
						}
						$arr_Data[] = $str_Value;
						$arr_Data = array_unique($arr_Data);
						$this->m_arr_Values[$str_Field] = $arr_Data;
					}
					else
					{
						$this->m_arr_Values[$str_Field] = $str_Value;
					}
				}
			}
		}

		public function get_Solr_Document()
		{
			$obj_Doc = new Apache_Solr_Document();

			foreach ($this->m_arr_Values as $key => $value)
			{
				if (is_array($value))
				{
					foreach ($value as $datum)
					{
						$obj_Doc->addField($key, $datum);
					}
				}
				else
				{
					$obj_Doc->$key = $value;
				}
			}

			//print_r($obj_Doc);
			return $obj_Doc;
		}
		
		public static function get_Constants()
		{
			$arr_Output = array();

			$arr_Output['C_STR_FIELD_CLASSIFICATION'] = self::C_STR_FIELD_CLASSIFICATION;
			$arr_Output['C_STR_FIELD_CLIENT'] = self::C_STR_FIELD_CLIENT;
			$arr_Output['C_STR_FIELD_CONTENT'] = self::C_STR_FIELD_CONTENT;
			$arr_Output['C_STR_FIELD_HARVEST_DATE'] = self::C_STR_FIELD_HARVEST_DATE;
			$arr_Output['C_STR_FIELD_ID'] = self::C_STR_FIELD_ID;
			$arr_Output['C_STR_FIELD_INDEX_DATE'] = self::C_STR_FIELD_INDEX_DATE;
			$arr_Output['C_STR_FIELD_LANGUAGE'] = self::C_STR_FIELD_LANGUAGE;
			$arr_Output['C_STR_FIELD_LIKED'] = self::C_STR_FIELD_LIKED;
			$arr_Output['C_STR_FIELD_ORIG_ID'] = self::C_STR_FIELD_ORIG_ID;
			$arr_Output['C_STR_FIELD_PROPERTY_OPTIONS'] = self::C_STR_FIELD_PROPERTY_OPTIONS;
			$arr_Output['C_STR_FIELD_PUBLISH_DATE'] = self::C_STR_FIELD_PUBLISH_DATE;
			$arr_Output['C_STR_FIELD_TITLE'] = self::C_STR_FIELD_TITLE;
			$arr_Output['C_STR_FIELD_SOURCE'] = self::C_STR_FIELD_SOURCE;
			$arr_Output['C_STR_FIELD_SCORE'] = self::C_STR_FIELD_SCORE;
			$arr_Output['C_STR_FIELD_SUMMARY'] = self::C_STR_FIELD_SUMMARY;
			$arr_Output['C_STR_FIELD_TAGS'] = self::C_STR_FIELD_TAGS;
			$arr_Output['C_STR_FIELD_VIEWED'] = self::C_STR_FIELD_VIEWED;

			return $arr_Output;
		}
	}
